using System;
using System.IO;
using System.Runtime.Remoting;
using System.Threading;
using System.Web;
using Sedna.Core.Controller;
using Sedna.Core.Persistence;
using Sedna.Core.Security;
using log4net;

namespace Sedna 
{
	/// <summary>
	/// Summary description for Global.
	/// </summary>
	public class Global : System.Web.HttpApplication
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		private ILog log = null;
		private IPrincipalInjector principalInjector;	    

		public Global()
		{
			InitializeComponent();
		}	
	    		
		protected void Application_Start(Object sender, EventArgs e)
		{
			log4net.Config.XmlConfigurator.Configure();
//			log4net.Config.DOMConfigurator.Configure();
			log = LogManager.GetLogger(typeof(Global));

		    log.Info("Application Start");
		    
            RemotingConfiguration.Configure(HttpContext.Current.Server.MapPath("~/BT.config"), false);
		    
		    try
			{
			    log.Info("Initializing Persistence DAL...");
                WebPstSessionFactoryInitializer.InitializeFactory(this.Application); ;
				log.Info("Persistence DAL initialized successfully");
			}
			catch(Exception ex)
			{
				log.Fatal("Error while trying to initialize Persistence DAL", ex);
				throw ex;
			}
		    
			principalInjector = (IPrincipalInjector)SpringContextFactory.GetContext().GetObject("runtime.PrincipalInjector");
		}
	    
 
		protected void Session_Start(Object sender, EventArgs e)
		{
            
		}

		protected void Application_BeginRequest(Object sender, EventArgs e)
		{
			IPstSessionFactory sessionFactory = (IPstSessionFactory)SpringContextFactory.GetContext().GetObject("infra.PstSessionFactory");
			sessionFactory.BeginOrJoinHbmSession();
		}

		protected void Application_EndRequest(Object sender, EventArgs e)
		{
			IPstSessionFactory sessionFactory = (IPstSessionFactory)SpringContextFactory.GetContext().GetObject("infra.PstSessionFactory");
			sessionFactory.CloseSessionIfAny();
		    
            //we might get a problem by switching off the caching capabilities completely, though by now it is the simplies way of fighting with browser cache. this is to be explored further
            //Context.Response.AppendHeader("Pragma", "ho-cache");
            //Context.Response.AppendHeader("Cache-Control ", "no-cache,must-revalidate");

            HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.AddDays(-1));
            HttpContext.Current.Response.Cache.SetNoStore();
            HttpContext.Current.Response.Cache.SetNoServerCaching();
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);

		}

		protected void Application_AuthenticateRequest(Object sender, EventArgs e)
		{
            UserMapper.RestoreCurrentState();
            IAuthenticator authenticator = (IAuthenticator)SpringContextFactory.GetContext().GetObject("runtime.Authenticator");
            authenticator.InjectPrincipal(Context);               
		}

		protected void Application_Error(Object sender, EventArgs e)
		{
			
		}

		protected void Session_End(Object sender, EventArgs e)
		{
		}

		protected void Application_End(Object sender, EventArgs e)
		{
            WebPstSessionFactoryInitializer.DestroyFactory(this.Application);
            log.Info("Application End");
		}

		protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
		{
		    //UserMapper.RestoreCurrentState();
			if(principalInjector == null)
			{
				principalInjector = (IPrincipalInjector)SpringContextFactory.GetContext().GetObject("runtime.PrincipalInjector");
			}
			try
			{
				principalInjector.BeforeRequest(Context);
			}
			catch
			{
				PrincipalCookieUtil.SignOut(Context);
			}
		}

		protected void Application_PostRequestHandlerExecute(Object sender, EventArgs e)
		{
			if(principalInjector == null)
			{
				principalInjector = (IPrincipalInjector)SpringContextFactory.GetContext().GetObject("runtime.PrincipalInjector");
			}
			principalInjector.AfterRequest(Context);
		    UserMapper.UpdateState();
		}
	    
	    protected void Applivation_AcquireRequestState(Object sender, EventArgs e)
	    {                
	    }
	    		
		#region Web Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.components = new System.ComponentModel.Container();
		}
		#endregion
	}
}

